package com.mini.mybatis.reflection;

import java.lang.reflect.Field;
import java.util.Map;

/**
 * 简化版元对象类
 * 提供对象属性访问的基本功能
 */
public class MetaObject {
    
    private final Object originalObject;
    
    private MetaObject(Object object) {
        this.originalObject = object;
    }
    
    /**
     * 创建MetaObject实例
     * @param object 目标对象
     * @return MetaObject实例
     */
    public static MetaObject forObject(Object object) {
        if (object == null) {
            return null;
        }
        return new MetaObject(object);
    }
    
    /**
     * 获取属性值
     * @param name 属性名
     * @return 属性值
     */
    public Object getValue(String name) {
        if (originalObject == null) {
            return null;
        }
        
        // 如果是Map类型，直接从Map中获取
        if (originalObject instanceof Map) {
            return ((Map<?, ?>) originalObject).get(name);
        }
        
        // 使用反射获取字段值
        try {
            Field field = findField(originalObject.getClass(), name);
            if (field != null) {
                field.setAccessible(true);
                return field.get(originalObject);
            }
        } catch (Exception e) {
            // 忽略异常，返回null
        }
        
        return null;
    }
    
    /**
     * 设置属性值
     * @param name 属性名
     * @param value 属性值
     */
    public void setValue(String name, Object value) {
        if (originalObject == null) {
            return;
        }
        
        // 如果是Map类型，直接设置到Map中
        if (originalObject instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (Map<String, Object>) originalObject;
            map.put(name, value);
            return;
        }
        
        // 使用反射设置字段值
        try {
            Field field = findField(originalObject.getClass(), name);
            if (field != null) {
                field.setAccessible(true);
                field.set(originalObject, value);
            }
        } catch (Exception e) {
            // 忽略异常
        }
    }
    
    /**
     * 检查是否有指定的属性
     * @param name 属性名
     * @return 是否存在该属性
     */
    public boolean hasProperty(String name) {
        if (originalObject == null) {
            return false;
        }
        
        if (originalObject instanceof Map) {
            return ((Map<?, ?>) originalObject).containsKey(name);
        }
        
        return findField(originalObject.getClass(), name) != null;
    }
    
    /**
     * 获取原始对象
     * @return 原始对象
     */
    public Object getOriginalObject() {
        return originalObject;
    }
    
    /**
     * 查找字段（包括父类）
     * @param clazz 类
     * @param fieldName 字段名
     * @return 字段对象
     */
    private Field findField(Class<?> clazz, String fieldName) {
        while (clazz != null && clazz != Object.class) {
            try {
                return clazz.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass();
            }
        }
        return null;
    }
}